#pragma once
#include "usart.h"
#include <stdbool.h>
#define Printf_UART USART1

#define USART_MALLOC 0 /* 串口接收缓冲区使用malloc动态分配内存 */

//使用LIFO模式
#define UART_DATA_LIFO

struct USART_Data;
typedef void (*uartCallBack)(struct USART_Data*);

typedef enum {
	DMA_MODE = 0,
	IT_MODE
} UsartMode;

typedef struct USART_Data {
  UART_HandleTypeDef *huart;
  uint8_t rxBuffer; /* HAL库使用的串口接收缓冲 */

  /*  接收状态
   *  bit15，      接收完成标志
   *  bit14，      接收到0x0d
   *  bit13~0，    接收到的有效字节数目
   */
  uint16_t usart_rx_sta;    
  uint16_t rxSize_Max;  /* 接收缓冲大小 */
  /* 接收缓冲, 最大rxSize_Max个字节,
  如果是静态分配，则要自己分配好把指针传入Init函数，
  如果使用动态分配，则会在Init中动态分配 */
#ifdef UART_DATA_LIFO
    uint8_t* usart_rx_buf[3];
    uint8_t* nextReadPtr;
    uint16_t readDataSize;
    uint8_t* processPtr;
    uint16_t processDataSize;
    uint8_t* writePtr;
#else
  uint8_t *usart_rx_buf;   
#endif
  uartCallBack callback; /*中断完成后执行的函数*/
  struct USART_Data *next;
} USART_Data;
#if USART_MALLOC == 1
uint8_t USART_DataTypeInit(USART_Data *me, UART_HandleTypeDef *huart,
                        uint16_t rxSize_Max, uint8_t receiveMode,uartCallBack callback);
#else 
uint8_t USART_DataTypeInit(USART_Data *me, UART_HandleTypeDef *huart,uint8_t* rxBuffer,
						uint16_t rxSize_Max,UsartMode receiveMode,uartCallBack callback);
#endif

#ifdef UART_DATA_LIFO
uint8_t* uartDataProcessLock(USART_Data* this);
void uartDataProcessUnlock(USART_Data* this);
/**
 * @brief 获取当前处理的缓冲区的长度
 * 
 * @param me 
 * @return uint16_t 
 * @note 请在uartDataProcessLock()之后调用此函数
 */
static inline uint16_t USART_DataGetReceivedLen(USART_Data *me)
{
    return (me->processDataSize);
}
static inline bool USART_DataIsReceived(USART_Data *me)
{
    return (me->nextReadPtr != NULL);
}
#else
/// @brief 数据接收是否完成
/// @param  me 指向要查看的串口的数据结构体的指针
/// @return true 接收完成 false 接收未完成
/// @note 记得在串口接收完成后调用USART_DataResetReceivedFlag()清除接收完成标志位
static inline bool USART_DataIsReceived(USART_Data *me)
{
    return (me->usart_rx_sta & 0x8000);
}
/// @brief 串口接收到的数据长度
/// @param  me 指向要查看的串口的数据结构体的指针
/// @return  接收到的数据长度，最大为2^14-1
static inline uint16_t USART_DataGetReceivedLen(USART_Data *me)
{
    return (me->usart_rx_sta & 0x3fff);
}

/// @brief 清除接收完成标志位
/// @param  me 指向要查看的串口的数据结构体的指针
static inline void USART_DataResetReceivedFlag(USART_Data *me)
{
    me->usart_rx_sta &= 0x3fff;//清空接收状态
    //me->usart_rx_sta &= (~0x3fff);//清空接收长度
}
/**
 * @brief 清除接收长度的标志
 * 
 * @param me 指向要查看的串口的数据结构体的指针
 */
static inline void USART_DataCleanReceivedLen(USART_Data *me)
{
    me->usart_rx_sta &= (~(0x3fff));//清空接收长度
}
/// @brief 获取串口接收缓冲区
/// @param  me 串口数据结构体指针
/// @return 串口接收缓冲区指针 
static inline uint8_t* USART_GetData(USART_Data *me)
{
    return me->usart_rx_buf;
}
#endif